﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
using Thor.Common;
using Thor.Domain;
using Thor.Exchange.Interop;
using Thor.Exchange.Interop.Exchange2007;
using Thor.Exchange.Interop.Exchange2010;
using Thor.Exchange.WebServices;

namespace Thor.Exchange.WindowsClient
{
    public partial class MainView : Form
    {
        private CalendarProviderBase _calendarProviderForMonitoring = null;
        private CalendarMonitor _monitor = null;

        public MainView()
        {
            InitializeComponent();
        }

        private void btnGetCalendarData_Click(object sender, EventArgs e)
        {
            ClearCalendarData();

            var provider = GetCalendarProvider();

            if (provider != null)
            {
                var calendar = GetCalendar(provider);

                if (calendar != null)
                    this.txtCalendarData.Text = calendar.ToString();
            }
        }

        private Calendar GetCalendar(CalendarProviderBase provider)
        {
            if (provider != null)
            {
                CalendarRequest request = GetCalendarRequest();

                return provider.GetCalendar(request);
            }
            else
                return null;
        }

        private CalendarRequest GetCalendarRequest()
        {
            NetworkCredential credential = new NetworkCredential(this.txtUserName.Text, this.txtPassword.Text, this.txtDomain.Text);
            string serviceUrl = this.txtServiceUrl.Text;
            string calendarId = this.txtCalendarId.Text;

            CalendarRequest request = new CalendarRequest()
            {
                CalendarId = calendarId,
                Credential = GetNetworkCredential(),
                EndDate = null,
                ServiceUrl = serviceUrl,
                StartDate = null
            };

            if (chkUseDates.Checked)
            {
                request.StartDate = this.dtpStart.Value;
                request.EndDate = this.dtpEnd.Value;
            }
            return request;
        }

        private NetworkCredential GetNetworkCredential()
        {
            if (!string.IsNullOrEmpty(this.txtDomain.Text))
                return new NetworkCredential(this.txtUserName.Text, this.txtPassword.Text, this.txtDomain.Text);
            else
                return new NetworkCredential(this.txtUserName.Text, this.txtPassword.Text);
        }

        private NetworkCredential GetAuthenticationNetworkCredential()
        {
            if (!string.IsNullOrEmpty(this.txtAuthenticationDomain.Text))
                return new NetworkCredential(this.txtAuthenticationUserName.Text, this.txtAuthenticationPassword.Text, this.txtAuthenticationDomain.Text);
            else
                return new NetworkCredential(this.txtAuthenticationUserName.Text, this.txtAuthenticationPassword.Text);
        }

        private CalendarProviderBase GetCalendarProvider()
        {
            CalendarProviderBase calendarProvider = null;

            if (this.cboProviders.SelectedIndex == 0)
                calendarProvider = new Thor.Exchange.WebServices.CalendarProvider();
            else if (this.cboProviders.SelectedIndex == 1)
            {
                if (cboVersion.SelectedIndex == 0)
                {
                    calendarProvider = new Thor.Exchange.Interop.Exchange2007.CalendarProvider();   
                }
                else if (cboVersion.SelectedIndex == 1)
                {
                    calendarProvider = new Thor.Exchange.Interop.Exchange2010.CalendarProvider();
                }
            }

            return calendarProvider;
        }

        private void ClearCalendarData()
        {
            this.txtCalendarData.Text = string.Empty;
            this.txtCalendarData.Refresh();
        }

        private void btnClearCalendarData_Click(object sender, EventArgs e)
        {
            ClearCalendarData();
        }

        private void btnBookIt_Click(object sender, EventArgs e)
        {
            ClearAppointmentResponse();

            var provider = GetCalendarProvider();
            var appointmentRequest = GetAppointmentRequest();
            var response = provider.BookAppointment(appointmentRequest);
            UpdateAppointmentResponse(response);
        }

        private void ClearAppointmentResponse()
        {
            chkSuccess.Checked = false;
            txtMessage.Text = string.Empty;
        }

        private AppointmentRequest GetAppointmentRequest()
        {
            var appointmentRequest = new AppointmentRequest();

            appointmentRequest.CalendarId = this.txtBookingCalendarId.Text;
            appointmentRequest.Credential = this.GetNetworkCredential();
            appointmentRequest.EndTime = this.dtpBookingEnd.Value;
            appointmentRequest.IgnoreBusyData = this.chkIgnoreBusyData.Checked;
            appointmentRequest.StartTime = this.dtpBookingStart.Value;
            appointmentRequest.Subject = this.txtSubject.Text;
            appointmentRequest.UseBookingAgent = this.chkBookingAgent.Checked;
            appointmentRequest.BookingAgentEmail = this.txtBookingAgentEmail.Text;
            appointmentRequest.ServiceUrl = this.txtServiceUrl.Text;

            return appointmentRequest;
        }

        private void UpdateAppointmentResponse(AppointmentResponse response)
        {
            chkSuccess.Checked = response.Success;
            txtMessage.Text = response.Message;
        }

        private void btnAuthenticate_Click(object sender, EventArgs e)
        {
            Authenticate();
        }

        private void Authenticate()
        {
            UpdateAuthenticationResult(GetCalendarProvider().Authenticate(GetAuthenticationNetworkCredential(), this.txtServiceUrl.Text));
        }

        private void UpdateAuthenticationResult(AuthenticationResult result)
        {
            chkAuthenticationSuccess.Checked = result.Success;
            txtAuthenticationMessage.Text = result.Message;
        }

        private void btnStartMonitoring_Click(object sender, EventArgs e)
        {
            btnStartMonitoring.Enabled = false;
            btnStopMonitoring.Enabled = true;

            _calendarProviderForMonitoring = GetCalendarProvider();

            if (_calendarProviderForMonitoring != null)
            {
                var request = GetCalendarRequest();
                int interval = Convert.ToInt32(this.nudInterval.Value);
                
                var parameters = new CalendarMonitorParameters();
                parameters.Provider = _calendarProviderForMonitoring;
                parameters.Interval = interval;
                parameters.Request = request;

                _monitor = new CalendarMonitor(parameters);
                _monitor.CalendarChanged += new CalendarChangedEventHandler(CalendarProviderForMonitoring_CalendarChanged);
                _monitor.Start();
            }
        }

        private void CalendarProviderForMonitoring_CalendarChanged(object sender, CalendarChangedEventArgs e)
        {
            if (this.txtCalendarData.InvokeRequired)
            {
                BeginInvoke(new MethodInvoker(delegate() { CalendarProviderForMonitoring_CalendarChanged(sender, e); }));
            }
            else
            {
                if (e.Calendar != null)
                    this.txtCalendarData.Text = e.Calendar.ToString();
                else
                    this.txtCalendarData.Text = "No calendar data found.";
            }
        }

        private void btnStopMonitoring_Click(object sender, EventArgs e)
        {
            btnStartMonitoring.Enabled = true;
            btnStopMonitoring.Enabled = false;

            if (_monitor != null)
                _monitor.Stop();
        }
    }
}